import React, {CSSProperties} from "react";
import {Input, Cascader as AntdCascader, Form as AntdForm,} from 'antd';
import {VJsonComponent} from "../../factory";
import _ from 'lodash'
import {YvanEvent} from "../../types";
import {apply, YvanEventBind, YvanEventDispatch} from "../../utils/helper";
import {DataComponentProp} from "../../datasource";
import {FormItemBaseState, FormItemVJSon, VJsonFormItemBase} from "./VJsonFormItemBase";
import * as Extend from '../../extend'
import {toJS} from "mobx";

export interface CascaderVJsonProp extends FormItemVJSon<Cascader> {
    addonAfter?: string | React.ReactNode
    addonBefore?: string | React.ReactNode
    //支持清除
    allowClear?: boolean
    //默认获取焦点	boolean	false
    autoFocus?: boolean
    //是否有边框	boolean	true
    bordered?: boolean
    //当此项为 true 时，点选每级菜单选项值都会发生变化	boolean	false
    changeOnSelect?: boolean
    //是否默认展开下拉菜单	boolean	-
    defaultOpen?: boolean
    //指定默认选中的条目	string[] | number[]
    defaultValue?: string[] | number[]
    //是否禁用	boolean	false
    disabled?: boolean
    //次级菜单的展开方式，可选 'click' 和 'hover'
    expandTrigger?: 'click'|'hover'
    //当下拉列表为空时显示的内容
    notFoundContent?: string
    //自定义浮层类名
    popupClassName?: string
    //浮层预设位置：bottomLeft bottomRight topLeft topRight 默认bottomLeft
    popupPlacement?: 'bottomLeft'|'bottomRight'|'topLeft'|'topRight'
    //控制浮层显隐
    popupVisible?: boolean
    //在选择框中显示搜索框 默认 false
    showSearch?: boolean
    //选择框默认文字	string	-
    placeholder?: string
    //选择框大小
    size?: 'large' | 'middle' | 'small'



    // 选中 option，或 input 的 value 变化时，调用此函数	function(value, option:Option | Array<Option>)	-
    onChange?: YvanEvent<Cascader>
    // 	显示/隐藏浮层的回调 (value) => void
    onPopupVisibleChange?: YvanEvent<Cascader>
}

export interface CascaderVJsonDataProp extends CascaderVJsonProp, DataComponentProp<Cascader> {

}

export interface CascaderState extends FormItemBaseState<Cascader> {

}

@VJsonComponent({
    view: 'cascader'
})
//@ts-ignore
export default class Cascader extends VJsonFormItemBase<Cascader, CascaderVJsonDataProp, CascaderState> {
    static defaultProps = {
        allowClear: true,
        idField: 'value',
        labelField: 'label',
        parentField: 'parentValue',
        data: [],
        rules: [],
        visible: true,
        valueSpliter: '/'
    }

    constructor(props: any) {
        super(props, Cascader.defaultProps);

        if (this.valueIsArray()) {
            this.defaultValue = this.valueSplit(this.defaultValue)
        }
    }

    private valueSplit(value?: string | string[]) {
        if (_.isArray(value)) {
            return value
        }
        if (!value) {
            return []
        }
        return value.split(this.props.vjson.valueSpliter)
    }

    private valueJoin(value?: string | string[]) {
        if (_.isArray(value)) {
            return value.join(this.props.vjson.valueSpliter)
        }
        if (!value) {
            return ''
        }
        return value
    }

    private valueIsArray() {
        return (this.props.vjson.mode === 'multiple' || this.props.vjson.mode === 'tags')
    }

    get treeData() {
        const _data: any[] = [];
        const templateMap: any = {};
        const idKey = this.props.vjson.idField || 'value';
        const parentIdKey = this.props.vjson.parentField || 'parentValue';
        const copyData = _.cloneDeep(toJS(this.data));
        _.forEach(copyData, (item, index)=>{
            _.set(templateMap, '' + item[idKey], item);
        })
        _.forEach(copyData, (item, index)=>{
            if (templateMap[item[parentIdKey]]) {
                const children = _.get(templateMap[item[parentIdKey]], 'children');
                if (!children || !_.isArray(children)) {
                    _.set(templateMap[item[parentIdKey]], 'children', [item]);
                } else {
                    children.push(item)
                }

            } else {
                _data.push(item);
            }
        })
        return _data;
    }


    protected onValueChange(value: any) {
        value = this.valueJoin(value)
        if (value !== this.value) {
            this.value = value
            YvanEventDispatch(this.props.vjson.onChange, this, value)
        }
    }

    /**
     * 从控件值到实体 (control -> entity) 的转换 normalizeToEntity
     */
    normalizeToEntity(value: any) {
        if (this.valueIsArray()) {
            return this.valueJoin(value)
        }
        return value
    }

    /**
     * 从实体值到控件 (entity -> control) 的转换 normalizeToEntity
     */
    normalizeToControl(value: any) {
        if (this.valueIsArray()) {
            return this.valueSplit(value)
        } else {
            return this.valueJoin(value)
        }
    }

    protected get _isRootFormItem() {
        return false
    }

    protected renderWrapper(): JSX.Element {
        if (Extend.isDebugMode()) {
            console.log('RenderCascader', this.toString(), this.loading)
        }

        const fieldOption = {
            label: this.props.vjson.labelField,
            value: this.props.vjson.idField,
            children: 'children',
        }

        const addonAfter =
            (typeof this.props.vjson.addonAfter === 'undefined')
                ? null
                : (<span className="ant-input-group-addon">
                        {
                            apply(this, this.props.vjson.addonAfter)
                        }
                </span>)

        return (
            <span className="ant-input-group-wrapper">
                <span className="ant-input-wrapper ant-input-group">
                    <AntdForm.Item noStyle
                                   {...this._getFormItemBindProperty(false)}
                    >
                        {/*@ts-ignore*/}
                        <AntdCascader key={this.key} view_id={this.key} aria-roledescription={this.view}
                                  showSearch={true}
                            // filterOption={this._filterOption.bind(this)}
                                  options={this.treeData}
                                  allowClear={apply(this, this.props.vjson.allowClear)}
                                  autoFocus={apply(this, this.props.vjson.autoFocus)}
                                  bordered={apply(this, this.props.vjson.bordered)}
                                  changeOnSelect={this.props.vjson.changeOnSelect}
                                  disabled={apply(this, this.props.vjson.disabled)}
                                  style={toJS(this.props.vjson.style)}
                                  //@ts-ignore
                                  loading={_.trim(this.loading)}
                                  onBlur={YvanEventBind(this.props.vjson.onBlur, this)}
                                  onChange={this.onValueChange.bind(this)}
                                  onPopupVisibleChange={YvanEventBind(this.props.vjson.onPopupVisibleChange, this)}
                                  onFocus={YvanEventBind(this.props.vjson.onFocus, this)}
                                  onSelect={YvanEventBind(this.props.vjson.onSelect, this)}
                                  displayRender={(value)=>value}
                                  open={this.props.vjson.open}
                                  placeholder={apply(this, this.props.vjson.placeholder)}
                                  fieldNames={fieldOption}
                                  size={apply(this, this.props.vjson.size)}
                        >
                        </AntdCascader>
                    </AntdForm.Item>
                    {
                        addonAfter
                    }
                </span>
            </span>
        )
    }
}
